package com.sihai.ehr.service.impl;

import com.sihai.core.DataAccessor;
import com.sihai.core.QueryCreator;
import com.sihai.ehr.model.biz.AuditType;
import com.sihai.ehr.model.biz.Auditing;
import com.sihai.ehr.service.AuditService;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.math.NumberUtils;
import org.hibernate.Query;
import org.hibernate.Session;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * @author: wxn
 * @since: 12-7-11 下午9:54
 */
@Service("auditService")
public class AuditServiceImpl implements AuditService {
    @Resource
    private DataAccessor dataAccessor;

    //查询某个审核过程数(即一个审核流程由多少个审核完成)
    public Long findAuditFlowCount(final Long organizationId, final AuditType auditType) {
        Long count = dataAccessor.findUnique(Long.class, new QueryCreator() {
            @Override
            public Query createQuery(Session session) {
                Query query = session.createQuery("select count(a.id) from Auditing a where a.auditingNo = :auditType and a.organization.id = :organization");
                query.setParameter("auditType", auditType);
                query.setParameter("organization", organizationId);
                return query;
            }
        });
        return count == null ? 0L : count;
    }

    @Override
    public List<Auditing> findAudits(Long organizationId, AuditType auditType) {
        return dataAccessor.findByHql(Auditing.class, "from Auditing a where a.auditingNo=? and a.organization.id=? order by seq asc", new Object[]{auditType, organizationId}, null, null);
    }

    //add.wxn:2012.10.17#通过指定审核类型＋指定ID查找审核配置
    @Override
    public List<Auditing> findAudits(Long organizationId, AuditType auditType, Long tid) {
        return dataAccessor.findByHql(Auditing.class, "from Auditing a where a.auditingNo=? and a.organization.id=? and a.auditingTargetId=? order by seq asc", new Object[]{auditType, organizationId, tid}, null, null);
    }
    
    @Override
    public List<Auditing> findAuditsTIDByCurrentLoginUserId(Long organizationId, AuditType auditType, Long userId) {
        return dataAccessor.findByHql(Auditing.class, "from Auditing a where a.auditingNo=? and a.organization.id=? and a.employee.id=? order by seq asc", new Object[]{auditType, organizationId, userId}, null, null);
    }

    @Override
    public void save(Auditing auditing) {
        if(auditing != null){
            dataAccessor.save(auditing);
        }
    }

    //批量配置
    @Override
    public void save(Auditing auditing, String batchIds) {
        if(auditing != null && StringUtils.isNotBlank(batchIds) && auditing.getAuditingTargetId() != null && auditing.getAuditingTargetId() > 0){
            String[] ids = StringUtils.split(batchIds, ",");//批量添加/更新的id
            if(ids == null || ids.length == 0){
                return;
            }

            List<Auditing> audits = dataAccessor.findByHql(Auditing.class, "from Auditing a where a.auditingNo=? and a.organization.id=? and a.auditingTargetId=? order by seq asc", new Object[]{auditing.getAuditingNo(), auditing.getOrganization().getId(), auditing.getAuditingTargetId()}, null, null);
            if(audits == null || audits.isEmpty()){
                return;
            }
            
            for(int i=0; i<ids.length; i++){
                Long tid = NumberUtils.createLong(ids[i]);
                if(tid  <= 0 || tid.longValue() == auditing.getAuditingTargetId().longValue()){
                    continue;
                }
                for(Auditing a : audits){
                    Auditing aud = new Auditing();
                    aud.setAuditingNo(a.getAuditingNo());
                    aud.setAuditingTargetId(tid);
                    aud.setAuditingSerialNo(a.getAuditingSerialNo());
                    aud.setDuty(a.getDuty());
                    aud.setEmployee(a.getEmployee());
                    aud.setOrganization(a.getOrganization());
                    aud.setIndicator(a.getIndicator());
                    aud.setSeq(a.getSeq());
                    dataAccessor.save(aud);
                }
            }
        }
    }

    @Override
    public void remove(Long aid){
        if(aid != null && aid > 0){
            dataAccessor.delete(dataAccessor.get(Auditing.class, aid));
        }
    }

    @Override
    public Auditing get(Long id) {
        if(id == null){
            return null;
        }
        return dataAccessor.get(Auditing.class, id);
    }

    @Override
    public void removeAll(final Auditing auditing) {
        if(auditing == null || auditing.getOrganization() == null || auditing.getOrganization().getId() == null || auditing.getAuditingNo() == null){
            return;
        }
        
        this.dataAccessor.batchUpdate(new QueryCreator() {
			@Override
			public Query createQuery(Session session) {
				Query query = session.createQuery("delete from Auditing a where a.auditingNo=:auditingNo and a.organization.id=:organizationId");
                query.setParameter("auditingNo", auditing.getAuditingNo());
                query.setParameter("organizationId", auditing.getOrganization().getId());
                return query;
			}
		});
    }

    @Override
    public void removeAll(final Auditing auditing, final String batchIds) {
        if(auditing == null || auditing.getOrganization() == null || auditing.getOrganization().getId() == null || auditing.getAuditingNo() == null || StringUtils.isBlank(batchIds)){
            return;
        }

        this.dataAccessor.batchUpdate(new QueryCreator() {
            @Override
            public Query createQuery(Session session) {
                String hql = String.format("delete from Auditing a where a.auditingNo=:auditingNo and a.auditingTargetId in (%s) and a.organization.id=:organizationId", batchIds);
                Query query = session.createQuery(hql);
                query.setParameter("auditingNo", auditing.getAuditingNo());
                query.setParameter("organizationId", auditing.getOrganization().getId());
                return query;
            }
        });
    }


    @Override
    public void saveOrders(String[] orders) {
        if(orders == null || orders.length == 0){
            return;
        }
        
        for(String order : orders){
            int index = order.indexOf(":");
            if(index == -1){
                continue;
            }
            Long aid = NumberUtils.createLong(StringUtils.substring(order, 0, index));
            Integer seq = NumberUtils.createInteger(StringUtils.substring(order, index+1, order.length()));
            if(aid > 0 && seq > 0){
                Auditing audit = dataAccessor.get(Auditing.class, aid);
                if(audit != null){
                    audit.setSeq(seq);
                    dataAccessor.save(audit);
                }
            }
        }
    }
}
